package com.gc.logger.printer

import android.content.Context
import android.util.Log
import com.gc.logger.LogUtils
import com.gc.logger.entity.LogEntity
import com.gc.logger.interfaces.ILogPrinter
import java.io.File
import java.io.FileWriter
import java.io.IOException
import java.text.SimpleDateFormat
import java.util.*

class FileLogPrinter(override var logType: LogUtils.LogType = LogUtils.LogType.File) : ILogPrinter {
    var filePath: String? = null
    private val sLoggingFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
    private val sLoggingTodayFormat = SimpleDateFormat("yyyy-MM-dd")
    constructor(filePath: String) : this() {
        this.filePath = filePath
    }

    override fun log(context: Context, logEntity: LogEntity) {
        if (filePath == null) {
            filePath = LogUtils.defFilePath
        }
        var tag = "${logEntity.defTag}:${logEntity.tag}"
        var fileWriter: FileWriter? = null
        try {
            val logFile: File = getLogFile(filePath!!)
            val content: String = getLogContent(logEntity.priority, tag, logEntity.message)
            fileWriter = FileWriter(logFile, true)
            fileWriter.append(content)
            fileWriter.flush()
            fileWriter.close()
        } catch (e: Exception) {
            if (fileWriter != null) {
                try {
                    fileWriter.flush()
                    fileWriter.close()
                } catch (e1: IOException) {
                }
            }
        }
    }

    private fun getLogContent(priority: Int, tag: String, message: String): String {
        val date: String = sLoggingFormat.format(Date())
        return String.format(LogUtils.LOG_CONTENT_FORMAT,
            date,
            getLogLevelString(priority),
            tag,
            message)
    }

    private fun getLogFile(logPath: String): File {
        val fileDir = File(logPath)
        if (!fileDir.exists()) {
            fileDir.mkdirs()
        }
        val today: String = sLoggingTodayFormat.format(Date())
        var newFileCount = 0
        var newFile: File
        var existingFile: File? = null
        newFile = File(fileDir, String.format("%s_%s.txt", today + "_log_", newFileCount))
        while (newFile.exists()) {
            existingFile = newFile
            newFileCount++
            newFile = File(fileDir, String.format("%s_%s.txt", today + "_log_", newFileCount))
        }
        return if (existingFile != null) {
            if (existingFile.length() >= LogUtils.MAX_BYTES) {
                newFile
            } else existingFile
        } else newFile
    }

    private fun getLogLevelString(level: Int): String? {
        when (level) {
            Log.VERBOSE -> return "V"
            Log.ERROR -> return "E"
            Log.INFO -> return "I"
            Log.WARN -> return "W"
        }
        return "D"
    }

}